const debounceMap = new Map();              //防抖参数

function objExpansionMap(obj) {            //obj展平成非嵌套map
    let map = new Map();
    switch (true) {
        case obj === null: case obj === undefined:
            return obj;
        case /string|number|function/.test(typeof obj):
            map.set(0, obj);            //单个值不用拆开
            return map;
    }

    let root = Object.entries(obj);     //根
    let ind = [0];                      //子在何层(深度),第几个(序列)-序列数组
    let tmpInd, tmpChild, types;
    let parent = root.concat();         //父
    let child, lens, tmpParent; //子、子键值对中值的长度、暂存父
    let indMap = new Map();             //序列表

    for (let i = 0; i < parent.length; i++) {
        parent != tmpParent && (ind[ind.length - 1] = i);   //判断父更新

        tmpInd = ind.concat();                                //临时ind
        child = getItem(root, ind);                         //找子

        lens = 0; tmpChild = null;

        if (child[1] !== null && child[1] !== undefined) {
            lens = Object.keys(child[1]).length;
        }

        if (lens > 0) {                         //子长不为零
            types = "level";
            ind.push(0);
            parent = Object.entries(child[1]);  //进入子级
            i = -1;
        } else {                                //子长为0
            tmpChild = child[1];
            if (typeof child[1] === "function") {
                types = "link";
            } else {
                types = "other";
            }
            if (typeof child[1] === "object") {
                if (i < parent.length - 1) {        //非末尾
                    if (ind.length > 1) {               //非第一层
                        let broInd = ind.concat();
                        broInd[broInd.length - 1] += 1;
                        //无弟，跳过，因为空集也会占一个序列，不跳过会出错
                        if (getItem(root, broInd) == undefined) { continue; }
                    } else {
                        continue;
                    }
                }
            }
        }

        if (i == parent.length - 1) {               //末尾
            tmpParent = undefined;

            //找父的弟
            while (tmpParent == undefined) {
                if (ind.length > 1) {
                    ind.pop();
                }

                ind[ind.length - 1] += 1;
                tmpParent = getItem(root, ind);

                if (ind.length <= 1) {
                    break;
                }
            }

            //判断结束
            if (ind.length > 1 || tmpParent != undefined) {
                parent = tmpParent;
                i = -1;
            }

        }

        let value;
        if (tmpChild === null) {
            value = {
                name: child[0],
                type: types,
            }
        } else {
            value = {
                name: child[0],
                value: tmpChild,
                type: types,
            }
        }
        let key = tmpInd.join(",");

        indMap.set(child[0], () => {
            return map.get(key);
        });

        map.set(key, value);                        //写入map

    }

    return {
        map: map,
        indMap: indMap
    };                                     //返回map
}

function getItem(item, ind) {               //根据序列数组ind找子
    for (let j = 0; j < ind.length; j++) {
        item = item[ind[j]];                    //找子
        if (j == ind.length - 1) { break; }     //末尾
        item instanceof Array ?                 //将数组默认为键值对，并判断
            item = Object.entries(item[1]) :    //子为数组，返回子之值的键值对
            item = Object.entries(item);        //子非数组，返回自身键值对
    }
    return item;                                //返回子
}

function autoReName(names, obj) {
    //去重，并生成不重复的名称
    //names在obj中存在，返回生成的不重复值，否则返回原值
    let re = /\d+$/;
    let endNum = 0;
    let stops = true;

    while (stops) {
        switch (true) {
            case obj instanceof Map:
                !obj.get(names) && (stops = false);
                break;
            case obj instanceof Array:
                obj.indexOf(names) < 0 && (stops = false);
                break;
            case obj instanceof Object:
                !(names in obj) && (stops = false);
                break;
            default:
                stops = false;
                console.log("autoReName的第二参数请传入Map、Array或obj");
        }
        if (stops == false) {
            break;
        } else {
            endNum++;
            names = names.replace(re, "") + endNum;
        }
    }
    return names;
}

function waits(time) {                       //await调用，等待效果
    return new Promise(resolve => {
        setTimeout(() => {
            resolve();
        }, time);
    })
}

function debounce(time, cb, names) {        //await调用，调用cb并防抖
    //time为防抖间隔，names为区分不同调用的名称
    let timer = debounceMap.get(names);
    if (timer) {
        clearTimeout(timer);
        debounceMap.delete(names);
    }
    return new Promise(resolve => {
        timer = setTimeout(() => {
            resolve(cb());
        }, time);
        debounceMap.set(names, timer);
    })
}
//将方法组合成一个对象，暴露出去
export {
    objExpansionMap,
    getItem,
    autoReName,
    debounce,
    waits
}

// document.body.scrollWidth
    // 在ProvidePlugin添加全局函数时，export后边可以不跟default
    // 在main.js中通过app.config.globalProperties注册全局属性时export 后边要跟 default，不然会报错
